﻿// -------------------- iSharePoint -------------------- //
// 
//  Company:	IT Complex, LLC
//  Project:	Smart.Common
//  File name:	CacheExts.cs
//  Developer:	Igor Solomatov
//  Created:	20.10.2012
// 
// -------------------- iSharePoint -------------------- //

using System;
using System.Web.Caching;

namespace Smart
{
	public static class CacheExts
	{
		/// <summary>
		/// Returns value from <paramref name="cache"/> by <paramref name="key"/>
		/// </summary>
		public static TValueType SafeGet<TValueType>(this Cache cache, string key)
		{
			return (TValueType)cache.Get(key);
		}

		/// <summary>
		/// Returns value from <paramref name="cache"/> by <paramref name="key"/>
		/// </summary>
		public static TValueType SafeGet<TValueType>(this Cache cache, string key, TValueType defaultValue)
		{
			return (TValueType)(cache[key] ?? defaultValue);
		}

		/// <summary>
		/// Sets <paramref name="value"/> by <paramref name="key"/> in <paramref name="cache"/>
		/// </summary>
		public static void SafeSet<TValueType>(this Cache cache, string key, TValueType value, TimeSpan absoluteExpiration)
		{
			cache.Insert(key, value, null, DateTime.Now.Add(absoluteExpiration), Cache.NoSlidingExpiration);
		}

		/// <summary>
		/// Sets <paramref name="value"/> by <paramref name="key"/> in <paramref name="cache"/>
		/// </summary>
		public static void SafeSet<TValueType>(this Cache cache, string key, TValueType value, TimeSpan absoluteExpiration, TimeSpan slidingExpiration)
		{
			if (absoluteExpiration == TimeSpan.Zero)
				cache.Insert(key, value, null, Cache.NoAbsoluteExpiration, slidingExpiration);
			else
				cache.Insert(key, value, null, DateTime.Now.Add(absoluteExpiration), Cache.NoSlidingExpiration);
		}

		/// <summary>
		/// Sets <paramref name="value"/> by <paramref name="key"/> in <paramref name="cache"/>
		/// </summary>
		public static void SafeSet<TValueType>(this Cache cache, string key, TValueType value, DateTime absoluteExpiration, TimeSpan slidingExpiration)
		{
			if (absoluteExpiration == DateTime.MinValue)
				cache.Insert(key, value, null, Cache.NoAbsoluteExpiration, slidingExpiration);
			else
				cache.Insert(key, value, null, absoluteExpiration, Cache.NoSlidingExpiration);
		}

		/// <summary>
		/// Returns value from <paramref name="cache"/> by <paramref name="key"/>, uses <paramref name="loader"/> to add non existing value
		/// </summary>
		public static TValueType SafeGet<TValueType>(this Cache cache, string key, TimeSpan absoluteExpiration, Func<string, TValueType> loader)
		{
			var value = cache[key];

			TValueType typedValue;

			if (value != null)
				typedValue = (TValueType)value;
			else
				cache.Insert(key, typedValue = loader(key), null, DateTime.Now.Add(absoluteExpiration), Cache.NoSlidingExpiration);

			return typedValue;
		}

		/// <summary>
		/// Returns value from <paramref name="cache"/> by <paramref name="key"/>, uses <paramref name="loader"/> to add non existing value
		/// </summary>
		public static TValueType SafeGet<TValueType>(this Cache cache, string key, TimeSpan absoluteExpiration, TimeSpan slidingExpiration, Func<string, TValueType> loader)
		{
			var value = cache[key];

			TValueType typedValue;

			if (value != null)
				typedValue = (TValueType)value;
			else
			{
				typedValue = loader(key);

				if (absoluteExpiration == TimeSpan.Zero)
					cache.Insert(key, typedValue, null, Cache.NoAbsoluteExpiration, slidingExpiration);
				else
					cache.Insert(key, typedValue, null, DateTime.Now.Add(absoluteExpiration), Cache.NoSlidingExpiration);
			}

			return typedValue;
		}
	}
}